//自定义函数：event3d.js
//刘鑫：2019-9-4
//蒲瞻星：2019-9-9 修复两处重大bug：1.屏幕中莫名奇妙的click事件 2.坐标面有时候click没反应
//蒲瞻星：2019-9-10 增加鼠标靠到坐标轴上坐标轴被选中
//刘鑫：2019-9-12 增加移动物体函数，初步对threejs函数生成的mesh进行移动，尚不能对通过ajax渲染出来的mesh的物体移动？？


// 函数目标：所有三维显示区的事件均会被捕捉到，并执行相应操作
import {Raycaster, Vector2} from "./three.module.js";
import {CylinderBufferGeometry} from "./three.module.js";
import {MeshPhongMaterial} from "./three.module.js";
import {Mesh} from "./three.module.js";
import {EdgesGeometry, LineBasicMaterial, LineSegments} from "./three.module.js";
import {grid_to_xoy, grid_to_xoz, grid_to_yoz} from "./helpers.js";
import {arrow_change} from "./helpers.js";
import {TransformControls} from "./TransformControls.js";



//主显示区与鼠标位置的一一映射，所有的点击事件均依赖于此
var cadScene=document.getElementById("w_right");    //获取cad显示区，以下针对cad显示区的操作全部会被捕捉到
cadScene.addEventListener('mousemove', onMoveMousePosition, false);
cadScene.addEventListener('click', onClickMousePosition, false);
cadScene.addEventListener('mouseup',MouseMoveUp,false);
var raycaster = new Raycaster();                    // 记录mouse的位置,mouse的值在鼠标移动的时候是一直在更新的。
var moveMouse=new Vector2();
var clickMouse=null;
var clickMouse_for_Axes=null;
var clickMouse_for_reference=null;
//针对点击高亮的全局变量
var selected_click_target_color_r = 0;
var selected_click_target_color_g = 0;
var selected_click_target_color_b = 0;
var selected_click_target = null;
//针对移动选中的边缘高亮
var selected_move_target_edge=null;

var selected_move_target = null;



function onMoveMousePosition( event ) {

    event.preventDefault();
    moveMouse.x=(event.clientX-cadScene.offsetLeft)/cadScene.clientWidth*2-1;//针对于嵌入到区域中的现象，则要考虑鼠标偏差
    moveMouse.y=-(event.clientY-document.getElementById("workspace").offsetTop)/cadScene.clientHeight*2+1;
}

function onClickMousePosition( event ) {

    event.preventDefault();
    clickMouse = new Vector2();
    clickMouse.x=(event.clientX-cadScene.offsetLeft)/cadScene.clientWidth*2-1;//针对于嵌入到区域中的现象，则要考虑鼠标偏差
    clickMouse.y=-(event.clientY-document.getElementById("workspace").offsetTop)/cadScene.clientHeight*2+1;

    clickMouse_for_Axes=new Vector2();
    clickMouse_for_Axes.x=(event.clientX-cadScene.offsetLeft)/cadScene.clientWidth*2-1;//针对于嵌入到区域中的现象，则要考虑鼠标偏差
    clickMouse_for_Axes.y=-(event.clientY-document.getElementById("workspace").offsetTop)/cadScene.clientHeight*2+1;

    //坐标系的选择只有在可以选择之后才会记录
    if(can_selected_reference){
        clickMouse_for_reference=new Vector2();
        clickMouse_for_reference.x=(event.clientX-cadScene.offsetLeft)/cadScene.clientWidth*2-1;//针对于嵌入到区域中的现象，则要考虑鼠标偏差
        clickMouse_for_reference.y=-(event.clientY-document.getElementById("workspace").offsetTop)/cadScene.clientHeight*2+1;
    }

    // todo 为什么在中键旋转的时候，仍会触发点亮物体？

}

function MouseMoveUp() {
}

//---------------------------------------------------
//----------功能一：点击高亮---------------------------
// --------------------------------------------------

function clickSelection(scene,camera) {

    if(clickMouse!==null) {
        //首先存储之前选中的目标的颜色，方便点击其他目标后回复颜色。
        if (selected_click_target) {
            selected_click_target.material.color.setRGB(selected_click_target_color_r,
                selected_click_target_color_g,
                selected_click_target_color_b);
        }
        // 执行选中
        raycaster.setFromCamera(clickMouse, camera);
        var intersects = raycaster.intersectObjects(scene.children);
        clickMouse = new Vector2();//click的点使用完毕后立即重置，要不然空间某处会一直存在
        if (intersects.length > 0) {
            var target = intersects[0].object;
            //如果不是坐标才选中颜色
            selected_click_target_color_r = target.material.color.r;
            selected_click_target_color_g = target.material.color.g;
            selected_click_target_color_b = target.material.color.b;
            target.material.color.setRGB(1., 0.65, 0.);
            selected_click_target = target;

        }
        clickMouse=null;
    }
    return target;
}

//---------------------------------------------------
//----------功能二：框选高亮--------------------------
// --------------------------------------------------

function boxSelection(){


}

//*---------------------------------------------------
//----------功能三：移动鼠标高亮实体轮廓--------------------------
// --------------------------------------------------
function moveHlightEdge(scene,camera) {

    var edge1=scene.getObjectByName('edge1');
    var edge2=scene.getObjectByName('edge2');
    if (selected_move_target) {
        edge1.material.color.setRGB(0,0,0);
        edge2.material.color.setRGB(0,0,0);
    }
    // 执行选中
    raycaster.setFromCamera(moveMouse, camera);
    var intersects = raycaster.intersectObjects(scene.children);
    if (intersects.length > 0) {
        var target = intersects[0].object;
        var target_name=target.name;
        console.log(target_name);

        //如果触碰到的是geometry类型。则点亮此geometry的实体的相关线
            if (target_name==='geometry1'){
                edge1.material.color.setRGB(1., 0.65, 0.);
                selected_move_target = target;
            }else if (target_name==='geometry2'){
                edge2.material.color.setRGB(1., 0.65, 0.);
                selected_move_target = target;

            }

        //如果触碰到的是line类型。则将此line特别点亮，同时line的特殊点也显示出来。

    }



}

//------------------------------------------------------------------------
//----------功能四：高亮主坐标系_鼠标移至坐标系颜色加深_高亮主坐标系--------------------------
// -----------------------------------------------------------------------
var temp=null;
var temp_color=null;
function highlightMainAxes(mainAxes,camera) {

    //点击一次，scene中内容改变的，需要调取渲染器进行相应的渲染。
    raycaster.setFromCamera( moveMouse, camera );

    var intersects = raycaster.intersectObjects( mainAxes.children);
    if(intersects.length>0) {
        for (var i = 0; i < intersects.length; i++) {

            var intersect = intersects[0].object;
            //移动物体
            var name = intersects[0].object.name;
            if (temp) temp.material.color.setHex(temp_color);
            temp = intersect;
            temp_color = intersect.material.color.getHex();
            if (name === 'yoz') intersect.material.color.setHex(0x00ffff);
            else if (name === 'xoy') intersect.material.color.setHex(0x66cd00);
            else if (name === 'xoz') intersect.material.color.setHex(0xff4040);
        }
    }
    else {
        if (temp) temp.material.color.setHex(temp_color);
        temp_color = null;
        temp = null;
    }
}

var arrow_only_add_one=false;
var temp_arrow=null;
function highlightMainAxes_Arrow(mainAxes_arrow,camera) {
    raycaster.setFromCamera( moveMouse, camera );

    var intersects = raycaster.intersectObjects( mainAxes_arrow.children);
    if(intersects.length>0) {

        var intersect = intersects[0].object;
        //移动物体
        var name = intersects[0].object.name;
        if (arrow_only_add_one === false) {
            if (temp_arrow) {
                arrow_change(temp_arrow.name, false);
                arrow_only_add_one = false;                //移除之后可以再次选中
            }
            temp_arrow = intersect;
            arrow_change(name, true);                     //将对应的X、Y、Z轴变为选中
            arrow_only_add_one = true;                     //这可以选中一次，进入选中状态后不可重复选中
        }
    }
    else {
        if (temp_arrow) {
            arrow_change(temp_arrow.name,false);
            arrow_only_add_one = false;     //接触已选中坐标轴中的线
            }
        temp_arrow = null;
    }
}



//------------------------------------------------------------------------
//----------功能五：高亮视角指示器_鼠标单击视角指示器的对应面，视角旋转至对应面--------------------------
// -----------------------------------------------------------------------

function selected_reference(mainAxes,camera) {
    if(clickMouse_for_reference!==null) {   //当没有单击的时候，界面刷新的时候什么都不会执行
        if (can_selected_reference) {      //当点击草体图标或字体后这个boolean才会变成true，表示我们可以选择坐标面了
            // 执行选中
            raycaster.setFromCamera(clickMouse_for_reference, camera);
            var intersects = raycaster.intersectObjects(mainAxes.children);
            if (intersects.length > 0) {
                var target = intersects[0].object;
                switch (target.name) {
                    case 'xoy' : {
                        grid_to_xoy();
                        is_selected_reference = true;
                        //记录已经选中了坐标中的平面了，这样的话点击草图就没有反应了
                        //只有在视图的转化完毕之后，才会恢复这个，从而可以重新点击草图然后点击平面了
                        selected_xoy = true;
                        break;
                    }
                    case 'xoz' : {
                        grid_to_xoz();
                        is_selected_reference = true;
                        selected_xoz = true;
                        break;
                    }
                    case 'yoz' : {
                        grid_to_yoz();
                        is_selected_reference = true;
                        selected_yoz = true;
                        break;
                    }
                }
            }
        }
        clickMouse_for_reference = null;//重置点击的位置
    }
}

//------------------------------------------------------------------------
//----------功能六：鼠标单击坐标轴，将单击的信息发送给后端--------------------------
// -----------------------------------------------------------------------
function selected_axes(mainAxes_arrow,camera){
    if(clickMouse_for_Axes!==null) {
        raycaster.setFromCamera(clickMouse_for_Axes, camera);
        var intersects = raycaster.intersectObjects(mainAxes_arrow.children);
        if (intersects.length > 0) {
            var target = intersects[0].object;
            switch (target.name) {
                case 'X' : {
                    alert('X');
                    break;
                }
                case 'Y' : {
                    alert('Y');
                    break;
                }
                case 'Z' : {
                    alert('Z');
                    break;
                }
            }
        }
        clickMouse_for_Axes = null;          //重置点击的位置
    }
}





//------------------------------------------------------------------------
//----------功能五：高亮视角指示器_鼠标移至视角指示器的对应面，对应面高亮--------------------------
// -----------------------------------------------------------------------

function highlightSmallAxes(scene,camera){


}


//------------------------------------------------------------------------
//----------功能五：鼠标移至坐标系颜色加深_高亮主坐标系--------------------------
// -----------------------------------------------------------------------

function translateObject(object,camera,renderer,render,controls,scene){

    var control = new TransformControls( camera, renderer.domElement );
    control.addEventListener( 'change', render );
    control.addEventListener( 'dragging-changed', function ( event ) {
        controls.enabled = ! event.value; //在拖拽的时候，相机不再能够移动。
    } );
    control.attach( object );
    scene.add( control );

}
//---------------------------------------------------
//----------功能五：旋转物体--------------------------
// --------------------------------------------------
function rotateObject(scene,camera) {

    //点击一次，scene中内容改变的，需要调取渲染器进行相应的渲染。
    raycaster.setFromCamera( mouse, camera );
    var intersects = raycaster.intersectObjects( scene.children);

    for ( var i = 0; i < intersects.length; i++ ) {

        //移动物体
        var mesh=intersects[ 0].object;
        mesh.translateX(5);

        //测试ajax

        var data = {
            data: JSON.stringify({
                "value": 'asdf'
            })
        };


        $.ajax({
            url: "/",
            type: 'POST',
            data: data,
            success: function (msg) {
                alert("ajax传输成功");
            },
            error: function (e) {
                alert("传输失败");
                console.log(e.status);
                console.log(e.responseText);
            }

        })

        //测试结束

    }
}


export {clickSelection,moveHlightEdge,boxSelection,translateObject,rotateObject,highlightMainAxes,
    highlightSmallAxes,selected_reference,highlightMainAxes_Arrow,selected_axes}